use apic::{APIC_INIT, CALIBRATED_TIMER_INITIAL, LAPIC};
use core::sync::atomic::Ordering;
use interrupts::IDT;
use limine::smp::Cpu;
use smp::CPUS;

use crate::START_SCHEDULE;

pub mod acpi;
pub mod apic;
pub mod gdt;
pub mod hpet;
pub mod interrupts;
pub mod smp;
pub mod sse;
pub mod syscall;

unsafe extern "C" fn ap_entry(smp_info: &Cpu) -> ! {
    CPUS.write().get(smp_info.lapic_id).load();
    IDT.load();

    while !APIC_INIT.load(Ordering::SeqCst) {}
    LAPIC.lock().enable();

    let timer_initial = CALIBRATED_TIMER_INITIAL.load(Ordering::SeqCst);
    LAPIC.lock().set_timer_initial(timer_initial);

    crate::syscall::init();

    crate::arch::sse::init();

    while !START_SCHEDULE.load(Ordering::SeqCst) {}
    debug!("Application Processor {} started", smp_info.id);

    loop {
        x86_64::instructions::interrupts::enable_and_hlt();
        crate::process::r#yield();
    }
}
